package engine;

import java.util.List;
import java.util.Set;

import controller.Manager;
import controller.human.Action;
import controller.human.User;
import java.awt.*;
import java.awt.geom.Line2D;
import java.io.*;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;


public class Statistics implements Statistics2Manager, Serializable {
    
    public static int CITIZEN_DIES = 50;
    public static int KILLER_DIES = 100;
    public static int DIFFERENCE_CONSTANT = 20;
    
	@SuppressWarnings("unused")
	private Manager manager;
        
        private Point[] lineKillers;
        private Point[] lineCitizens;
        private int gameRounds;
        private ArrayList<PlayersForRound> roundsResults = new ArrayList<PlayersForRound>();

	@Override
	public void init(Manager manager) {
		// TODO 
		this.manager = manager;
	}

	@Override
	public void startGame(Set<User> users) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void logUserChange(Set<User> users) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void startSession() {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void endSession(boolean citizensWin) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void logAction(User actor, User target, Action action, boolean result) {
		// TODO Auto-generated method stub
                System.out.println("am fost aici");
		System.out.println("statistics "+actor + " -> " + target + " (" + action + ") => " + result);
                //writeToFile();
                
                // if this was called at the end of a phase (night/day) an object of type PlayersForRound must be stored
        
                //TODO remove this test call
                drawStatistics();
        }

	
	
	@Override
	public List<Achievement> getAllAchievements(User user) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Achievement> getAllAchievements() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Achievement> getGameAchievements(User user) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Achievement> getGameAchievements() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Achievement> getSessionAchievements(User user) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Achievement> getSessionAchievements() {
		// TODO Auto-generated method stub
		return null;
	}
        
        @Override
        public int getTotalGameRounds(){
            
            return this.gameRounds;
        }
        
	@Override
	public void logAchievements(List<Achievement> achievements) {
		// TODO Auto-generated method stub
		
	}

        public static void save_Object(Serializable object, String fileName)throws IOException{
		ObjectOutputStream objstream = new ObjectOutputStream(new FileOutputStream (fileName));
		objstream.writeObject(object);
		objstream.close();
	}
	
        public static Object load_Object(String fileName)throws Exception{
		ObjectInputStream objstream = new ObjectInputStream(new FileInputStream (fileName));
		Object object = objstream.readObject();
		objstream.close();
		return object;
	}
        private void writeToFile(){
    
       try{
              
       
        File dir = new File(".");
        
        FileWriter fstream = new FileWriter("out.txt", true);
        BufferedWriter out = new BufferedWriter(fstream);
      
        out.close();
          }
       catch (Exception e){
             
           System.err.println("Error: " + e.getMessage());
         }
                
         
    }
  //********
  //** this method is responsible for drawing the game plot when the game ends
  //*** it is called at the and of the game
  //**********
     public void drawStatistics() {
		// TODO Auto-generated method stub
         
         //TODO get the PlayersForRound from list; the number of PlayersForRound represents the number of rounds
         //TODO remove the dummy data for PlayersForRound
        roundsResults.add(new PlayersForRound(4, 2));
        roundsResults.add(new PlayersForRound(3, 2));
        roundsResults.add(new PlayersForRound(3, 1));
        roundsResults.add(new PlayersForRound(3, 1));
        roundsResults.add(new PlayersForRound(2, 1));
       // roundsResults.add(new PlayersForRound(1, 1));
        //roundsResults.add(new PlayersForRound(0, 1));
        roundsResults.add(new PlayersForRound(2, 0));
         
	this.gameRounds = roundsResults.size();	
        lineKillers = new Point[this.gameRounds];
        lineCitizens = new Point[this.gameRounds];
        
        drawPlot();
	}
     
     private void drawPlot(){
        
         JFrame frame = new JFrame("Game Statistics ( the game was finished in "+(this.gameRounds - 1)+" rounds )");
         Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
         LinePanel panel = new LinePanel();
     
         System.out.println(screenSize.width+" "+screenSize.height);
         panel.lineOX.setLine( 10d,  screenSize.height-200, screenSize.width -20,screenSize.height-200 );
         panel.lineOY.setLine( 10d,  screenSize.height-200, 10,10);
     
         //build the arrays of points 
         int yStartCitizens = Math.round((screenSize.height - 20)/3) ;
         int yStartKillers = 2*yStartCitizens;
         PlayersForRound playersLastRound = roundsResults.get(0);
         lineKillers[0] = new Point(10, yStartKillers);
         lineCitizens[0] = new Point(10, yStartCitizens);
         int xStep = 0;
         if(this.gameRounds != 0) xStep = (int) Math.floor((screenSize.width - 20)/(this.gameRounds));
       
         int step = xStep;
         for (int i = 1; i < this.gameRounds; i++){
             PlayersForRound players = roundsResults.get(i);
             
             if(players.killers > 0 && players.killers <= players.citizens){
                int difference = (players.citizens - players.killers) * DIFFERENCE_CONSTANT;
                if(players.killers < playersLastRound.killers){
                 //a killer died during theday // KILLER_DIES
                  yStartCitizens = (yStartCitizens + KILLER_DIES - difference);
                  yStartKillers = (yStartKillers - KILLER_DIES - difference) ;
                }
                else if(players.citizens < playersLastRound.citizens){
                 //a citizen died during the night or during the day
                  
                  yStartCitizens = yStartCitizens -( - CITIZEN_DIES + difference);
                  yStartKillers = yStartKillers -( CITIZEN_DIES - difference) ;
                }
           
             }
             else{
                 //the game is over
                 if(players.killers == 0){
                     //citizens won
                     yStartCitizens = 10;
                    yStartKillers = screenSize.height-200 ;
                 }
                 else{
                     //killers won
                    yStartCitizens = screenSize.height-200;
                    yStartKillers = 10 ;
                 }
             }
             lineKillers[i] = new Point(step, yStartKillers);
             lineCitizens[i] = new Point(step, yStartCitizens);
             
             step += xStep;
             playersLastRound = players;
         }
 
         panel.lineCitizensArray = lineCitizens;
         panel.lineKillersArray = lineKillers;
 
	 frame.add(panel);
	 frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE );
         frame.setBounds(0,0,screenSize.width, screenSize.height);
	
	 frame.setVisible(true);
}

}
     
     
   //********
  //** this class represents the result after a game round; it contains the number of good and bad players
 //*** after a round this data is gona be stored in a file list so that at the end of the game the roundsResults array to be initiated with this datta
 //**********
      
